package com.example.sunsg.okhttptest.util;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.media.Image;
import android.media.MediaScannerConnection;
import android.media.ThumbnailUtils;

import com.example.sunsg.okhttptest.bean.ExifInterfaceImpl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Created by sunsg on 15/10/17.
 */
public class ImageUtil {

    /**图片默认大小*/
    public static final int IMAGE_DEFAULT_SIZE = 1600;

    /**
     * 图片压缩 但是没有存储exif信息
     *
     * @param sourcePath
     * @param targetPath
     * @return
     */
    public static boolean commonCompressPic(String sourcePath, String targetPath, int width, int height) {
        boolean isSuccess = false;
        Matrix matrix = new Matrix();
        BitmapFactory.Options opt = new BitmapFactory.Options();
        Bitmap rotateBitmap = null;
        Bitmap bitmap = null;
        Bitmap tempBitmap = null;
        if(width <= 0 || height <= 0){
            width = IMAGE_DEFAULT_SIZE;
            height = IMAGE_DEFAULT_SIZE;
        }
        try {

            ExifInterfaceImpl exif = new ExifInterfaceImpl(sourcePath);
            if (exif != null) {
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                matrix.postRotate(getPhotoOrientation(orientation));
            }
            opt.inJustDecodeBounds = true;//只取大小，不放在内存
            BitmapFactory.decodeFile(sourcePath, opt);
            opt.inSampleSize = calculateInSampleSize(opt, width, height);

            opt.inJustDecodeBounds = false;
            opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            opt.inTempStorage = new byte[16 * 1024];

            tempBitmap = BitmapFactory.decodeFile(sourcePath, opt);

            float tempBitmapH = tempBitmap.getHeight();
            float tempBitmapW = tempBitmap.getWidth();
            float tempSide = tempBitmapH + tempBitmapW;
            float tempHScale = tempBitmapH / tempSide;
            float tempWScale = tempBitmapW / tempSide;
            boolean tempHLonger = tempHScale > tempWScale;

            bitmap = ThumbnailUtils
                    .extractThumbnail(tempBitmap, (int) tempBitmapW, (int) tempBitmapH, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);

            float scale = 1;
            if (tempHLonger) {
                if (tempBitmapH > height) {
                    scale = height / tempBitmapH;
                }
            } else {
                if (tempBitmapW > width) {
                    scale = width / tempBitmapW;
                }
            }

            matrix.postScale(scale, scale);

            rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

            File file = new File(targetPath);
            FileOutputStream fos = new FileOutputStream(file);

            // 压缩完之后需要设置相关exif信息
            isSuccess = rotateBitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);//85压缩 85％

            fos.flush();
            fos.close();
            // 压缩后新生成的图片exif信息中经纬度没有了

        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        } finally {
            if (tempBitmap != null && !tempBitmap.isRecycled()) {
                tempBitmap.recycle();
            }
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
            if (rotateBitmap != null && !rotateBitmap.isRecycled()) {
                rotateBitmap.recycle();
            }
        }
        return isSuccess;
    }

    /**
     * 压缩图片
     *
     * @param sourcePath
     * @param width
     * @param height
     * @return
     */
    public static Bitmap commonCompressPic(String sourcePath, int width, int height) {
        Matrix matrix = new Matrix();
        BitmapFactory.Options opt = new BitmapFactory.Options();
        Bitmap rotateBitmap = null;
        Bitmap bitmap = null;
        Bitmap tempBitmap = null;

        try {
            if (width <= 0 || height <= 0) {
                width = IMAGE_DEFAULT_SIZE;
                height = IMAGE_DEFAULT_SIZE;
            }

            ExifInterfaceImpl exif = new ExifInterfaceImpl(sourcePath);
            if (exif != null) {
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                matrix.postRotate(getPhotoOrientation(orientation));
            }

            opt.inJustDecodeBounds = true;//只取大小，不放在内存
            BitmapFactory.decodeFile(sourcePath, opt);

            opt.inSampleSize = calculateInSampleSize(opt, width, height);
            opt.inJustDecodeBounds = false;
            opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            opt.inTempStorage = new byte[16 * 1024];

            tempBitmap = BitmapFactory.decodeFile(sourcePath, opt);

            float tempBitmapH = tempBitmap.getHeight();
            float tempBitmapW = tempBitmap.getWidth();

            bitmap = ThumbnailUtils
                    .extractThumbnail(tempBitmap, (int) tempBitmapW, (int) tempBitmapH, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);


            float scale = 1;
            float tempSide = tempBitmapH + tempBitmapW;
            float tempHScale = tempBitmapH / tempSide;
            float tempWScale = tempBitmapW / tempSide;
            boolean tempHLonger = tempHScale > tempWScale;
            if (tempHLonger) {
                if (tempBitmapH > height) {
                    scale = height / tempBitmapH;
                }
            } else {
                if (tempBitmapW > width) {
                    scale = width / tempBitmapW;
                }
            }

            matrix.postScale(scale, scale);

            rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        } finally {
            if (tempBitmap != null && !tempBitmap.isRecycled()) {
                tempBitmap.recycle();
            }
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }

        return rotateBitmap;
    }


    /**
     * 获得文件路径 exif 信息
     *
     * @param sourcePath
     * @return
     */
    public static int getPhotoOrientation(String sourcePath) {
        int orientation = -1;
        try {
            ExifInterfaceImpl exif = new ExifInterfaceImpl(sourcePath);
            if (exif != null) {
                orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            }
        } catch (Exception e) {

        }
        return orientation;
    }


    /**
     * 获取照片的方向
     *
     * @param orientation 方向
     * @return
     * @author sunsg
     * @since 2015-10-17
     */
    public static int getPhotoOrientation(int orientation) {
        int degree = 0;
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
            default:
                degree = 0;
                break;
        }
        return degree;
    }

    /**
     * 获得缩放大小
     *
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            final float totalPixels = width * height;
            final float totalReqPixelsCap = reqWidth * reqHeight * 2;
            while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                inSampleSize++;
            }
        }
        return inSampleSize;
    }

    /**
     * 通知系统在媒体库中生成缩略图
     *
     * @param context
     * @param file
     */
    public static void scanFile(Context context, File file) {
        MediaScannerConnection.scanFile(context, new String[]{file.getAbsolutePath()}, null, null);
    }

    /**
     * 获取资源文件的 option
     *
     * @param res
     * @param id
     * @return
     */
    public static BitmapFactory.Options getOptionsForResourceId(Resources res, int id) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 只读宽和高 不加载到内存
        BitmapFactory.decodeResource(res, id, options);
        return options;
    }

    /**
     * 获取文件路径的option
     *
     * @param filePath
     * @return
     */
    public static BitmapFactory.Options getOptionForFilePath(String filePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;// 只描边，不读取数据
        BitmapFactory.decodeFile(filePath, options);
        return options;
    }

    /**
     * 获得rect
     *
     * @param width
     * @param height
     * @return
     */
    private static Rect getScreenRegion(int width, int height) {
        return new Rect(0, 0, width, height);
    }


    /**
     * 资源文件获得bitmap
     *
     * @param res
     * @param id
     * @param options
     * @param screenWidth
     * @param screenHeight
     * @return
     */
    public static Bitmap getBitmapByResource(Resources res, int id, BitmapFactory.Options options, int screenWidth, int screenHeight) {
        if (options != null) {
            Rect r = getScreenRegion(screenWidth, screenHeight);
            int w = r.width();
            int h = r.height();
            int inSimpleSize = calculateInSampleSize(options, screenWidth, screenHeight);
            options.inSampleSize = inSimpleSize; // 设置缩放比例
            options.inJustDecodeBounds = false;
        }
        Bitmap b = null;
        try {
            b = BitmapFactory.decodeResource(res, id, options);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            b = null;
            System.gc();
        }
        return b;
    }

    /**
     * 本地路径获得图片
     *
     * @param path
     * @return
     */
    public static Bitmap getBitmapByPath(String path) {
        return getBitmapByPath(path, 0, 0);
    }

    /**
     * 本地路径获得图片
     *
     * @param path
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap getBitmapByPath(String path, int reqWidth, int reqHeight) {
        File file = new File(path);
        if (!file.exists()) {
            return null;
        }
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
        } catch (FileNotFoundException e1) {
            return null;
        }
        Bitmap b = null;
        int oriation = getPhotoOrientation(path);
        if (oriation == 6) {
            //横向的图
            b = commonCompressPic(path, reqWidth, reqHeight);
        } else {
            BitmapFactory.Options options = null;
            if (reqWidth != 0 && reqHeight != 0) {
                options = getOptionForFilePath(path);
                int inSimpleSize = calculateInSampleSize(options, reqWidth, reqHeight);
                options.inSampleSize = inSimpleSize; // 设置缩放比例
                options.inJustDecodeBounds = false;
            }
            try {
                b = BitmapFactory.decodeStream(in, null, options);
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                b = null;
                System.gc();
            }

            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return b;
    }

    /**
     * 输入转换为String
     *
     * @param inputStream
     * @return
     */
    private static String changeInputToString(InputStream inputStream) {

        String jsonString = "";
        ByteArrayOutputStream outPutStream = new ByteArrayOutputStream();
        byte[] data = new byte[1024];
        int len = 0;
        try {
            while ((len = inputStream.read(data)) != -1) {
                outPutStream.write(data, 0, len);
            }
            jsonString = new String(outPutStream.toByteArray());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonString;
    }

    /**
     * bitmap 转换为 byte[]
     * @param bmp
     * @param needRecycle
     * @return
     */
    public static byte[] bmpToByteArray(final Bitmap bmp,
                                        final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 把图片保存到文件里
     * @param paht
     * @param bitmap
     */
    public static void writeBitmapToFile(String paht,Bitmap bitmap){

        File tempFile = new File(paht);
        if(tempFile.exists()) {
            // 图像保存到文件中
            FileOutputStream foutput = null;
            try {
                foutput = new FileOutputStream(tempFile);
                if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, foutput)) {
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取圆角图片
     * @param bitmap
     * @return
     */
    public static Bitmap getRoundeBitmap(Bitmap bitmap){
        if(bitmap == null){
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float roundPx;
        float left,top,right,bottom,dst_left,dst_top,dst_right,dst_bottom;
        if (width <= height) {
            roundPx = width / 2;
            top = 0;
            bottom = width;
            left = 0;
            right = width;
            height = width;
            dst_left = 0;
            dst_top = 0;
            dst_right = width;
            dst_bottom = width;
        } else {
            roundPx = height / 2;
            float clip = (width - height) / 2;
            left = clip;
            right = width - clip;
            top = 0;
            bottom = height;
            width = height;
            dst_left = 0;
            dst_top = 0;
            dst_right = height;
            dst_bottom = height;
        }

        Bitmap output = Bitmap.createBitmap(width,
                height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect src = new Rect((int)left, (int)top, (int)right, (int)bottom);
        final Rect dst = new Rect((int)dst_left, (int)dst_top, (int)dst_right, (int)dst_bottom);
        final RectF rectF = new RectF(dst);

        paint.setAntiAlias(true);

        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, src, dst, paint);
        return output;
    }



    /**
     * 旋转图片
     * @param b
     * @param degrees
     * @return
     */
    public static Bitmap rotate(Bitmap b, int degrees) {
        if (degrees != 0 && b != null) {
            Matrix m = new Matrix();
            m.setRotate(degrees, (float) b.getWidth() / 2,
                    (float) b.getHeight() / 2);
            try {
                Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
                        b.getHeight(), m, true);
                if (b != b2) {
                    b.recycle();
                    b = b2;
                }
            } catch (OutOfMemoryError ex) {
                // We have no memory to rotate. Return the original bitmap.
            }
        }
        return b;
    }

}
